package elements.axis; 
import flash.display.Sprite;
import string.Utils;
import elements.Types.Style;

class YAxisBase extends Sprite {

	var stroke:Int;
	var tick_length:Int;
	var colour:String;
	var grid_colour:String;
	
	public var style:Style;
	
	var labels:YAxisLabelsBase;
	var user_labels:Array<String>;
	var user_ticks:Bool;
	
	function new( json:Dynamic, name:String )
	{
		super();
		//
		// If we set this.style in the parent, then
		// access it here it is null, but if we do
		// this hack then it is OK:
		//
		this.style = this.get_style();
		
		if( json[name] )
			Object_helper.merge_2( json[name], this.style );
			
		
		this.colour = Utils.get_colour( style.colour );
		this.grid_colour = Utils.get_colour( style['grid-colour'] );
		this.stroke = style.stroke;
		this.tick_length = style['tick-length'];
		
		// try to avoid infiniteloops...
		if ( this.style.steps == 0 )
			this.style.steps = 1;
			
		if ( this.style.steps < 0 )
			this.style.steps *= -1;
		
		if (this.style.labels != null &&
			this.style.labels.labels != null &&
			Std.is( this.style.labels.labels, Array) &&
			this.style.labels.labels.length > 0)
		{
			this.user_labels = new Array<String>();
			for ( label in this.style.labels.labels )
			{
				if (!Std.is(label, String)) {
					if (label.y != null) 
					{
						var tmpObj:{ y : String } = { y: label.y };
						if (label["grid-colour"])
						{
							tmpObj["grid-colour"] = Utils.get_colour(label["grid-colour"]);
						}
						else
						{
							tmpObj["grid-colour"] = this.grid_colour;
						}
						
						this.user_ticks = true;
						this.user_labels.push(tmpObj);
					}
				}
			}
		}

		
	}
	
	public function get_style():Dynamic { return null;  }
	
	//
	// may be called by the labels
	//
	public function set_y_max( m:Float ):Void {
		this.style.max = m;
	}
	
	public function get_range():Range {
		return new Range( this.style.min, this.style.max, this.style.steps, this.style.offset );
	}
	
	public function get_width():Float {
		return this.stroke + this.tick_length + this.labels.width;
	}
	
	public function die(): Void {
		
		//this.offset = null;
		this.style = null;
		if (this.labels != null) this.labels.die();
		this.labels = null;
		
		this.graphics.clear();
		while ( this.numChildren > 0 )
			this.removeChildAt(0);
	}
	
	public function resize(label_pos:Float, sc:ScreenCoords):Void { }
	
	function resize_helper(label_pos:Float, sc:ScreenCoords, right:Bool):Void {
		
		if( !right )
			this.labels.resize( label_pos, sc );
		else
			this.labels.resize( sc.right + this.stroke + this.tick_length, sc );
		
		if ( !this.style.visible )
			return;
		
		this.graphics.clear();
		this.graphics.lineStyle( 0, 0, 0 );
		
		// y axel grid lines
		//var every:Number = (this.minmax.y_max - this.minmax.y_min) / this.steps;
		
		// Set opacity for the first line to 0 (otherwise it overlaps the x-axel line)
		//
		// Bug? Does this work on graphs with minus values?
		//
		var i2:Int = 0;
		var i:Float;
		var y:Float;
		
		var min:Int = Math.min(this.style.min, this.style.max);
		var max:Int = Math.max(this.style.min, this.style.max);
		
		if ( this.style['grid-visible'] ) {
			//
			// draw GRID lines
			//
			if (this.user_ticks) 
			{
				for ( label in this.user_labels )
				{
					y = sc.get_y_from_val(label.y, right);
					this.graphics.beginFill(label["grid-colour"], 1);
					this.graphics.drawRect( sc.left, y, sc.width, 1 );
					this.graphics.endFill();
				}
			}
			else
			{
				//
				// hack: http://kb.adobe.com/selfservice/viewContent.do?externalId=tn_13989&sliceId=1
				//
				max += 0.000004;
				
				i = min;
					
				while ( i <= max) {
					
					y = sc.get_y_from_val(i, right);
					this.graphics.beginFill( this.grid_colour, 1 );
					this.graphics.drawRect( sc.left, y, sc.width, 1 );
					this.graphics.endFill();
					i+=this.style.steps ;
					
				}
			}
		}
		
		var pos:Float;
		
		if (!right)
			pos = sc.left - this.stroke;
		else
			pos = sc.right;
		
		// Axis line:
		this.graphics.beginFill( this.colour, 1 );
		this.graphics.drawRect( pos, sc.top, this.stroke, sc.height );
		this.graphics.endFill();
		
		// ticks..
		var width:Float;
		if (this.user_ticks) 
		{
			for ( label in this.user_labels )
			{
				y = sc.get_y_from_val(label.y, right);
				
				if ( !right )
					tick_pos = sc.left - this.stroke - this.tick_length;
				else
					tick_pos = sc.right + this.stroke;
				
				this.graphics.beginFill( this.colour, 1 );
				this.graphics.drawRect( tick_pos, y - (this.stroke / 2), this.tick_length, this.stroke );
				//this.graphics.drawRect( pos - this.tick_length, y - (this.stroke / 2), this.tick_length, this.stroke );
				//this.graphics.drawRect( left, y-(this.stroke/2), this.tick_length, this.stroke );
				this.graphics.endFill();
			}
		}
		else
		{
			i = min;
				
				// start at the bottom and work up:
			while ( i <= max) {
				
				// start at the bottom and work up:
				y = sc.get_y_from_val(i, right);
				
				var tick_pos:Float;
				if ( !right )
					tick_pos = sc.left - this.stroke - this.tick_length;
				else
					tick_pos = sc.right + this.stroke;
				
				this.graphics.beginFill( this.colour, 1 );
				this.graphics.drawRect( tick_pos, y - (this.stroke / 2), this.tick_length, this.stroke );
				//this.graphics.drawRect( pos - this.tick_length, y - (this.stroke / 2), this.tick_length, this.stroke );
				//this.graphics.drawRect( left, y-(this.stroke/2), this.tick_length, this.stroke );
				this.graphics.endFill();
					
				i+=this.style.steps ;
				
				// start at the bottom and work up:
			}
		}
	}
	
}
